// Enter your shader in this window
#define nThread 128


uint nGroupX = 1;
uint nGroupY = 1;
uint nGroupZ = 1;
uint cPass = 0;

Buffer<uint> g_CountBuffer_UINT1;
RWBuffer<uint> g_CountSumBuffer_RW_UINT1;

[numthreads( nThread,  1,  1)] //ThreadGroupCount = ceil((numVertex - 2^cPass) / nThread);
void cs_PrefixSum_UINT1(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex)
{
	
	uint _j = (Gid.z*nGroupY*nGroupX + Gid.y*nGroupX + Gid.x)*nThread + GTid.x;
	uint pow_pass = pow(2, cPass);
	uint _j_big = _j + pow_pass;
	uint dimCount = 0;
	g_CountBuffer_UINT1.GetDimensions(dimCount);
	
	if (_j_big < dimCount)
		g_CountSumBuffer_RW_UINT1[_j_big] = g_CountBuffer_UINT1[_j] + g_CountBuffer_UINT1[_j_big];
	if (_j < pow_pass)
		g_CountSumBuffer_RW_UINT1[_j] = g_CountBuffer_UINT1[_j];
}


Buffer<uint2> g_CountBuffer_UINT2;
RWBuffer<uint2> g_CountSumBuffer_RW_UINT2;

[numthreads( nThread,  1,  1)] //ThreadGroupCount = ceil((numVertex - 2^cPass) / nThread);
void cs_PrefixSum_UINT2(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex)
{
	
	uint _j = (Gid.z*nGroupY*nGroupX + Gid.y*nGroupX + Gid.x)*nThread + GTid.x;
	uint pow_pass = pow(2, cPass);
	uint _j_big = _j + pow_pass;
	uint dimCount = 0;
	g_CountBuffer_UINT2.GetDimensions(dimCount);
	
	if (_j_big < dimCount)
		g_CountSumBuffer_RW_UINT2[_j_big] = g_CountBuffer_UINT2[_j] + g_CountBuffer_UINT2[_j_big];
	if (_j < pow_pass)
		g_CountSumBuffer_RW_UINT2[_j] = g_CountBuffer_UINT2[_j];
}


Buffer<uint3> g_CountBuffer_UINT3;
RWBuffer<uint3> g_CountSumBuffer_RW_UINT3;

[numthreads( nThread,  1,  1)] //ThreadGroupCount = ceil((numVertex - 2^cPass) / nThread);
void cs_PrefixSum_UINT3(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex)
{
	
	uint _j = (Gid.z*nGroupY*nGroupX + Gid.y*nGroupX + Gid.x)*nThread + GTid.x;
	uint pow_pass = pow(2, cPass);
	uint _j_big = _j + pow_pass;
	uint dimCount = 0;
	g_CountBuffer_UINT3.GetDimensions(dimCount);
	
	if (_j_big < dimCount)
		g_CountSumBuffer_RW_UINT3[_j_big] = g_CountBuffer_UINT3[_j] + g_CountBuffer_UINT3[_j_big];
	if (_j < pow_pass)
		g_CountSumBuffer_RW_UINT3[_j] = g_CountBuffer_UINT3[_j];
}


Buffer<uint4> g_CountBuffer_UINT4;
RWBuffer<uint4> g_CountSumBuffer_RW_UINT4;

[numthreads( nThread,  1,  1)] //ThreadGroupCount = ceil((numVertex - 2^cPass) / nThread);
void cs_PrefixSum_UINT4(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex)
{
	
	uint _j = (Gid.z*nGroupY*nGroupX + Gid.y*nGroupX + Gid.x)*nThread + GTid.x;
	uint pow_pass = pow(2, cPass);
	uint _j_big = _j + pow_pass;
	uint dimCount = 0;
	g_CountBuffer_UINT4.GetDimensions(dimCount);
	
	if (_j_big < dimCount)
		g_CountSumBuffer_RW_UINT4[_j_big] = g_CountBuffer_UINT4[_j] + g_CountBuffer_UINT4[_j_big];
	if (_j < pow_pass)
		g_CountSumBuffer_RW_UINT4[_j] = g_CountBuffer_UINT4[_j];
}


Buffer<float> g_CountBuffer_FLOAT1;
RWBuffer<float> g_CountSumBuffer_RW_FLOAT1;

[numthreads( nThread,  1,  1)] //ThreadGroupCount = ceil((numVertex - 2^cPass) / nThread);
void cs_PrefixSum_FLOAT1(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex)
{
	
	uint _j = (Gid.z*nGroupY*nGroupX + Gid.y*nGroupX + Gid.x)*nThread + GTid.x;
	uint pow_pass = pow(2, cPass);
	uint _j_big = _j + pow_pass;
	uint dimCount = 0;
	g_CountBuffer_FLOAT1.GetDimensions(dimCount);
	
	if (_j_big < dimCount)
		g_CountSumBuffer_RW_FLOAT1[_j_big] = g_CountBuffer_FLOAT1[_j] + g_CountBuffer_FLOAT1[_j_big];
	if (_j < pow_pass)
		g_CountSumBuffer_RW_FLOAT1[_j] = g_CountBuffer_FLOAT1[_j];
}


Buffer<float2> g_CountBuffer_FLOAT2;
RWBuffer<float2> g_CountSumBuffer_RW_FLOAT2;

[numthreads( nThread,  1,  1)] //ThreadGroupCount = ceil((numVertex - 2^cPass) / nThread);
void cs_PrefixSum_FLOAT2(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex)
{
	
	uint _j = (Gid.z*nGroupY*nGroupX + Gid.y*nGroupX + Gid.x)*nThread + GTid.x;
	uint pow_pass = pow(2, cPass);
	uint _j_big = _j + pow_pass;
	uint dimCount = 0;
	g_CountBuffer_FLOAT2.GetDimensions(dimCount);
	
	if (_j_big < dimCount)
		g_CountSumBuffer_RW_FLOAT2[_j_big] = g_CountBuffer_FLOAT2[_j] + g_CountBuffer_FLOAT2[_j_big];
	if (_j < pow_pass)
		g_CountSumBuffer_RW_FLOAT2[_j] = g_CountBuffer_FLOAT2[_j];
}


Buffer<float3> g_CountBuffer_FLOAT3;
RWBuffer<float3> g_CountSumBuffer_RW_FLOAT3;

[numthreads( nThread,  1,  1)] //ThreadGroupCount = ceil((numVertex - 2^cPass) / nThread);
void cs_PrefixSum_FLOAT3(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex)
{
	
	uint _j = (Gid.z*nGroupY*nGroupX + Gid.y*nGroupX + Gid.x)*nThread + GTid.x;
	uint pow_pass = pow(2, cPass);
	uint _j_big = _j + pow_pass;
	uint dimCount = 0;
	g_CountBuffer_FLOAT3.GetDimensions(dimCount);
	
	if (_j_big < dimCount)
		g_CountSumBuffer_RW_FLOAT3[_j_big] = g_CountBuffer_FLOAT3[_j] + g_CountBuffer_FLOAT3[_j_big];
	if (_j < pow_pass)
		g_CountSumBuffer_RW_FLOAT3[_j] = g_CountBuffer_FLOAT3[_j];
}


Buffer<float4> g_CountBuffer_FLOAT4;
RWBuffer<float4> g_CountSumBuffer_RW_FLOAT4;

[numthreads( nThread,  1,  1)] //ThreadGroupCount = ceil((numVertex - 2^cPass) / nThread);
void cs_PrefixSum_FLOAT4(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex)
{
	
	uint _j = (Gid.z*nGroupY*nGroupX + Gid.y*nGroupX + Gid.x)*nThread + GTid.x;
	uint pow_pass = pow(2, cPass);
	uint _j_big = _j + pow_pass;
	uint dimCount = 0;
	g_CountBuffer_FLOAT4.GetDimensions(dimCount);
	
	if (_j_big < dimCount)
		g_CountSumBuffer_RW_FLOAT4[_j_big] = g_CountBuffer_FLOAT4[_j] + g_CountBuffer_FLOAT4[_j_big];
	if (_j < pow_pass)
		g_CountSumBuffer_RW_FLOAT4[_j] = g_CountBuffer_FLOAT4[_j];
}


technique11 Tech_PrefixSum_UINT1 {
   pass p0 
	{
        SetVertexShader( NULL );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
		SetComputeShader( CompileShader( cs_5_0, cs_PrefixSum_UINT1()));
    }
}

technique11 Tech_PrefixSum_UINT2 {
   pass p0 
	{
        SetVertexShader( NULL );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
		SetComputeShader( CompileShader( cs_5_0, cs_PrefixSum_UINT2()));
    }
}

technique11 Tech_PrefixSum_UINT3 {
   pass p0 
	{
        SetVertexShader( NULL );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
		SetComputeShader( CompileShader( cs_5_0, cs_PrefixSum_UINT3()));
    }
}

technique11 Tech_PrefixSum_UINT4 {
   pass p0 
	{
        SetVertexShader( NULL );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
		SetComputeShader( CompileShader( cs_5_0, cs_PrefixSum_UINT4()));
    }
}

technique11 Tech_PrefixSum_FLOAT1 {
   pass p0 
	{
        SetVertexShader( NULL );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
		SetComputeShader( CompileShader( cs_5_0, cs_PrefixSum_FLOAT1()));
    }
}


technique11 Tech_PrefixSum_FLOAT2 {
   pass p0 
	{
        SetVertexShader( NULL );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
		SetComputeShader( CompileShader( cs_5_0, cs_PrefixSum_FLOAT2()));
    }
}


technique11 Tech_PrefixSum_FLOAT3 {
   pass p0 
	{
        SetVertexShader( NULL );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
		SetComputeShader( CompileShader( cs_5_0, cs_PrefixSum_FLOAT3()));
    }
}


technique11 Tech_PrefixSum_FLOAT4 {
   pass p0 
	{
        SetVertexShader( NULL );
        SetGeometryShader( NULL );
        SetPixelShader( NULL );
		SetComputeShader( CompileShader( cs_5_0, cs_PrefixSum_FLOAT4()));
    }
}

